// 解决分支切换问题问题
let activeEffect
const data = {text: 'hello', ok: true}
const bucket = new WeakMap()

// 收集依赖
function track (target, key) {
  let depsMap = bucket.get(target)
  if (!depsMap) {
    bucket.set(target, depsMap = new Map())
  }
  let deps = depsMap.get(key)
  if (!deps) {
    depsMap.set(key, deps = new Set())
  }
  if (activeEffect) {
    deps.add(activeEffect)
    // ==== 2.新增
    activeEffect.deps.push(deps)
  }
}

// 触发事件
function trigger (target, key) {
  const depsMap = bucket.get(target)
  if (!depsMap) return
  const deps = depsMap.get(key)
  // 4. 方式set遍历中删除又添加导致的无限循环
  // deps && deps.forEach(effect => effect())
  const effectsToRun = new Set(deps)
  effectsToRun.forEach(effect => effect())
}

// 代理
const obj = new Proxy(data, {
  get(target, key) {
    track(target, key)
    return target[key]
  },
  set(target, key, value) {
    target[key] = value
    trigger(target, key)
  }
})

// ==== 新增
function cleanup (effectFn) {
  for (let i = 0; i < effectFn.deps.length; i++) {
    const deps = effectFn.deps[i]
    deps.delete(effectFn)
  }
  effectFn.deps.length = 0
}

// ==== 修改
function effect (fn) {
  const effectFn = () => {
    // 3.新增
    cleanup(effectFn)
    activeEffect = effectFn
    fn()
  }
  // 1. 新增
  effectFn.deps = []
  effectFn()
}

effect(() => {
  const value = obj.ok ? obj.text : '123123'
  console.log(value, 'value???')
})

obj.text = '123'

setTimeout(() => {
  obj.ok = false
  obj.text = 444
}, 1000)

/**
 * 解析:
 * 1. 将effectFn的依赖集合都存入effectFn的静态方法deps中
 * 2. 依赖集合增加副作用函数的之后, 也将依赖集合本身增加到副作用函数的deps中去
 * 3. 执行副作用函数之前, 调用cleanup将其之前的依赖统统删除
 * 4. 为了避免Set.formEach时反复删除增加元素导致死循环, 重新new Set(deps), 用新的集合来遍历
 */